package com.beta.admin.controller;

import com.baomidou.mybatisplus.plugins.Page;
import com.beta.admin.request.user.ReceiverRequest;
import com.beta.admin.support.web.BaseController;
import com.beta.admin.vo.GenderVo;
import com.beta.admin.vo.UserStatusVo;
import com.beta.admin.vo.UserTypesVO;
import com.beta.common.web.ContentType;
import com.beta.dto.user.UserSearchDto;
import com.beta.dto.user.UsersDto;
import com.beta.dto.version.ReceiverUpdateDto;
import com.beta.em.GenderType;
import com.beta.em.UserStatus;
import com.beta.em.UserType;
import com.beta.em.admins.AdminRolesType;
import com.beta.service.IUsersService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by lichao on 2017/1/13.
 */
@RestController
@RequestMapping(RequestMappingConstants.MAPPING_PREFIX + "/users")
public class UsersController extends BaseController {

    @Autowired
    private IUsersService usersService;

    @RequiresPermissions("users:list")
    @GetMapping(value = "", produces = ContentType.JSON)
    public Object getUsers(@RequestParam("name") String name,
                           @RequestParam("phone") String phone,
                           @RequestParam("cityName") String cityName,
                           @RequestParam("status") String status,
                           @RequestParam("type") String type) {
        UserSearchDto userSearchDto = new UserSearchDto();
        userSearchDto.setName(name);
        userSearchDto.setPhone(phone);
        userSearchDto.setCityName(cityName);
        userSearchDto.setStatus(status);
        userSearchDto.setType(type);
        if (!hasRole(AdminRolesType.SUPER.value)) {
            userSearchDto.setCityCode(getCurrentAdmin().getCityCode());
        }
        Page<UsersDto> usersPage = usersService.getUsers(getMybatisPage(), userSearchDto);
        return pageData(usersPage);
    }

    @GetMapping(value = "/status", produces = ContentType.JSON)
    public Object getUserStatus() {
        UserStatus[] values = UserStatus.values();
        List<UserStatusVo> statusVos = new ArrayList<UserStatusVo>();
        for (UserStatus status : values) {
            UserStatusVo statusVo = new UserStatusVo();
            statusVo.setName(status.getValue());
            statusVo.setValue(status.getCnValue());
            statusVos.add(statusVo);
        }
        return statusVos;
    }

    @GetMapping(value = "/types", produces = ContentType.JSON)
    public Object getUserTypes() {
        UserType[] types = UserType.values();
        List<UserTypesVO> userTypesVos = new ArrayList<UserTypesVO>();
        for (UserType type : types) {
            UserTypesVO userTypeVo = new UserTypesVO();
            userTypeVo.setTypeValue(type.getValue());
            userTypeVo.setTypeCnValue(type.getCnValue());
            userTypesVos.add(userTypeVo);
        }
        return userTypesVos;
    }

    @GetMapping(value = "/genders", produces = ContentType.JSON)
    public Object getGenders() {
        GenderType[] genders = GenderType.values();
        List<GenderVo> genderVos = new ArrayList<GenderVo>();
        for (GenderType gender : genders) {
            GenderVo genderVo = new GenderVo();
            genderVo.setCode(gender.toString());
            genderVo.setValue(gender.toCn());
            genderVos.add(genderVo);
        }
        return genderVos;
    }

    @RequiresPermissions("users:receivers:list")
    @GetMapping(value = "/{userId}/receivers", produces = ContentType.JSON)
    public Object getReceiversByUserId(@PathVariable("userId") Integer userId) {
        return pageData(usersService.getReceiversById(getMybatisPage(), userId));
    }

    @RequiresPermissions("users:receivers:view")
    @GetMapping(value = "/receivers/{receiverId}", produces = ContentType.JSON)
    public Object getReceiverById(@PathVariable("receiverId") Integer receiverId) {
        return usersService.getReceiverById(receiverId);
    }

    @RequiresPermissions("users:receivers:edit")
    @PutMapping(value = "/receivers/{receiverId}", produces = ContentType.JSON)
    public Object updateReceiver(@Valid @RequestBody ReceiverRequest request) {
        ReceiverUpdateDto receiverUpdateDto = new ReceiverUpdateDto();
        receiverUpdateDto.setAddress(request.getAddress());
        receiverUpdateDto.setId(request.getId());
        receiverUpdateDto.setUserPhone(request.getUserPhone());
        receiverUpdateDto.setDescription(request.getDescription());
        receiverUpdateDto.setUserName(request.getUserName());
        usersService.updateReceiver(receiverUpdateDto);
        return ok();
    }

    @RequiresPermissions("users:receivers:add")
    @PostMapping(value = "/{userId}/receivers", produces = ContentType.JSON)
    public Object createReceiver(@Valid @RequestBody ReceiverRequest request, @PathVariable Integer userId) {
        ReceiverUpdateDto receiverUpdateDto = new ReceiverUpdateDto();
        receiverUpdateDto.setAddress(request.getAddress());
        receiverUpdateDto.setId(request.getId());
        receiverUpdateDto.setUserPhone(request.getUserPhone());
        receiverUpdateDto.setDescription(request.getDescription());
        receiverUpdateDto.setUserName(request.getUserName());
        receiverUpdateDto.setUserId(userId);
        usersService.createReceiver(receiverUpdateDto, userId);
        return ok();
    }

    @RequiresPermissions("users:receivers:edit")
    @DeleteMapping(value = "/receivers/{receiverId}", produces = ContentType.JSON)
    public Object deleteReceiver(@PathVariable Integer receiverId) {
        usersService.deleteReceiver(receiverId);
        return ok();
    }

    @RequiresPermissions("users:view")
    @GetMapping(value = "/{userId}", produces = ContentType.JSON)
    public Object getUserDetailById(@PathVariable("userId") Integer userId) {
        return usersService.getUserDetailById(userId);
    }

    @RequiresPermissions("users:edit")
    @PatchMapping(value = "/{userId}/activate", produces = ContentType.JSON)
    public Object activeUser(@PathVariable("userId") Integer userId) {
        usersService.executeActiveUser(userId);
        return ok();
    }

    @RequiresPermissions("users:edit")
    @PatchMapping(value = "/{userId}/deny", produces = ContentType.JSON)
    public Object denyUser(@PathVariable("userId") Integer userId) {
        usersService.executeDenyUser(userId);
        return ok();
    }
}
